#include "TCPServer.h"
#include "config_protocol.h"

#include "drm_pipe/pipe_stream.h"
#include "drm_pipe/pipe_merge.h"
#include "drm_pipe/display_mode.h"

extern Capture cap[10];
extern struct plane_arg plane[10];
extern Pipe_Stream pipe_s[10];
//extern Pipe_Merge pipe_merge;


void TCPServer::setup(int port)
{
    /*套接字选项*/
    int opt = 1;
    /*(1) 创建套接字*/
    m_sockfd=socket(AF_INET,SOCK_STREAM,0);
    /*(2) 初始化地址结构*/
    memset(&serverAddress,0,sizeof(serverAddress));
    serverAddress.sin_family=AF_INET;
    serverAddress.sin_addr.s_addr=htonl(INADDR_ANY);
    serverAddress.sin_port=htons(port);
    /*(3) 绑定套接字和端口*/
    setsockopt(m_sockfd , SOL_SOCKET , SO_REUSEADDR , &opt , sizeof(opt));
    bind(m_sockfd,(struct sockaddr *)&serverAddress, sizeof(serverAddress));
    /*(4) 监听*/
    listen(m_sockfd,LISTENEQ);
}

void TCPServer::receive()
{
    while(1)
    {
        socklen_t sosize  = sizeof(clientAddress);
        m_newsockfd = accept(m_sockfd,(struct sockaddr*)&clientAddress,&sosize);
        inet_ntoa(clientAddress.sin_addr);
        if(m_newsockfd != -1) {
            pthread_create(&serverThread,NULL,&Task,(void *)m_newsockfd);
        }
    }
    close(m_sockfd);
    close(m_newsockfd);
}

void* TCPServer::Task(void *arg)
{
    int sockfd = (long)arg;
    pthread_detach(pthread_self());

    uint8_t buf[MAX_LINE] = {0};

    memset(buf , 0 , MAX_LINE);
    //接收客户端字符串
    if(sockfd != -1){

        int length = 0;
        while(1)
        {
//            length = recv(sockfd, buf+length,(sizeof(buf) - length),0) + length;
            length = recv(sockfd, buf,(sizeof(buf)),0);
            for(int i = 0; i < length; i++)
            {
                printf("1111###recv[%d] [%d][%02x]\n",length,i, buf[i]);
            }
            if(length <= 0){
                printf("recv length error...");
                break;
            }
//            else if (length < MAX_LINE) {
//                printf("2222#############recv[%d] [%s]\n",length, buf);
//                continue;
//            }
//            else if (length == MAX_LINE) {
//                printf("3333@@@@@@@@@@@@@@  recv[%d] [%s]\n",length, buf);
//                length = 0;
//            }

            Message recvMsg;
            memset(&recvMsg , 0 , sizeof(recvMsg));
            memcpy(&recvMsg, buf, sizeof (buf));
            //校验
            uint8_t CheckCode = getXor(buf, sizeof (buf)-4);
            printf("3333@@@@@@@@@@@@@@  recv_CheckCode[%02x] [%02x]\n",recvMsg.CheckCode, CheckCode);
            /*if(CheckCode == recvMsg.CheckCode)*/ {
                //校验通过
                data_analyse(recvMsg);
            }
        }
    }
//    close(sockfd);
    printf("client exit！\n");
    return nullptr;
}

void TCPServer::data_analyse(Message recvMsg)
{
    Pipe_Convert_Type convet_type=nv12_rgb;
//    Pipe_Convert_Type convet_type=nv12_nv12;
    printf(" identifi[%04x] [%02x]\n",recvMsg.MsgHead.identifi, recvMsg.MsgType);
    if(recvMsg.MsgHead.identifi == 0xD050)
    {
        if(recvMsg.MsgType != INVALID) {
            pipe_stop_all(pipe_s);
        }
        printf(" MsgType [%02x]\n", recvMsg.MsgType);
        switch (recvMsg.MsgType) {
        case VIDEO_LF: {
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_LF],&plane[0],convet_type);
            break;
        }
        case VIDEO_F:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_F],&plane[0],convet_type);
            break;
        }
        case VIDEO_RF: {
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_RF],&plane[0],convet_type);
            break;
        }
        case VIDEO_LB:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_LB],&plane[0],convet_type);
            break;
        }
        case VIDEO_RB:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_RB],&plane[0],convet_type);
            break;
        }
        case VIDEO_B:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_B],&plane[0],convet_type);
            break;
        }
        case VIDEO_DF:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_DF],&plane[0],convet_type);
            break;
        }
        case VIDEO_DB:{
            screen_mode(plane,10,screen123456);
            pipe_s[0].start(&cap[VIDEO_DB],&plane[0],convet_type);
            break;
        }
        case FRONT_PANO:{
            screen_mode(plane,10,screen123x4x5x6);
            for(int i=0;i<4;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case FRONT_LIGHT_PANO:{
            screen_mode(plane,10,screen14x25x36);
            for(int i=0;i<3;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_FORWARD_PANO:{
            screen_mode(plane,10,screen1x2x3x4x5x6);
            for(int i=0;i<5;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_FORWARD_LIGHT_PANO:{
            screen_mode(plane,10,screen1x25x3x4x6);
            for(int i=0;i<5;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_FORWARD_DF:{
            screen_mode(plane,10,screen1x2x3x4x5x6);
            for(int i=0;i<5;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_FORWARD_F:{
            screen_mode(plane,10,screen1x2x3x4x5x6);
            for(int i=0;i<5;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_BACK_PANO:{
            screen_mode(plane,10,screen1x2x3x456);
            for(int i=0;i<4;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case CAR_BACK_LIGHT_PANO:{
            screen_mode(plane,10,screen1x2x3x456);
            for(int i=0;i<4;i++)
                pipe_s[i].start(&cap[i],&plane[i],convet_type);
            break;
        }
        case INVALID:
            break;
        }
    }
}
uint8_t TCPServer::getXor(uint8_t* data, int length)
{
       uint8_t temp = data[0];
       for(int i=1;i < length;i++){
          temp^=data[i];
       }
       return temp;
}
